﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WAF.Server;
using WAF.Server.Ipc;
using System.Threading;
using System.Diagnostics;

namespace PerformanceTests
{
    public class PerformanceTestBase
    {
        protected AppServerCore appServer;
        protected WebServerCore webServer;
        protected int warmupIterations = 50000;
        protected int iterations = 100000;
        protected int theads = 10;
        int currentIteration = 0;
        int requestSend = 0;
        int requestRecceived = 0;
        Stopwatch watch = new Stopwatch();
        ManualResetEvent testsStart = new ManualResetEvent(false);
        ManualResetEvent watchStart = new ManualResetEvent(false);
        ManualResetEvent testsStop = new ManualResetEvent(false);


        public int Iterations
        {
            get { return this.iterations; }
            set { this.iterations = value; }
        }

        public int Treads
        {
            get { return this.theads; }
            set { this.theads = value; }
        }

        public virtual ContentRequest CreateRequest()
        {
            ContentRequest request = new ContentRequest();
            return request;
        }

        public virtual void SendRequest(ContentRequest request)
        {
            Interlocked.Increment(ref this.requestSend);
        }

        public virtual void RecceiveResponse(ContentResponse response )
        {
            Interlocked.Increment(ref this.requestRecceived);
        }

        public void WorkerThread()
        {
            testsStart.WaitOne();
            int currenIteration = Interlocked.Increment(ref this.currentIteration);
            while (currenIteration <= (iterations + warmupIterations))
            {
                if (currentIteration == warmupIterations + 1)
                {
                    watchStart.Set();
                    Interlocked.Exchange(ref requestSend, 0);
                    Interlocked.Exchange(ref requestRecceived,0);
                }
 
                ContentRequest request = CreateRequest();
                SendRequest(request);
                currenIteration = Interlocked.Increment(ref this.currentIteration);
            }
            testsStop.Set();
        }

        public void RunTest()
        {
            if (Debugger.IsAttached)
            {
                warmupIterations = 50;
                iterations = 1000;
            }

            for (int t = 0; t < theads; ++t)
            {
                Thread thread = new Thread(WorkerThread);
                thread.Start();
            }
            Thread.Sleep(100); // Gives the threads some time to block on the start event
            watch.Reset();
   
            testsStart.Set();
            Console.WriteLine("  Begin Warm Up");
            watchStart.WaitOne();
            watch.Start();
            Console.WriteLine("  Begin Measurement");
            testsStop.WaitOne();
            watch.Stop();
            Thread.Sleep(100);

            Console.WriteLine("  Elapsed Time (mS): " + ((double)watch.ElapsedTicks / Stopwatch.Frequency * 1000).ToString());
            Console.WriteLine("  Requests Send: " + requestSend.ToString());
            Console.WriteLine("  Requests Recceived: " + requestRecceived.ToString());
        }

    }
}
